<script lang="ts">
export default {
  name: "xt-table",
};
</script>

<script setup lang="ts">
import { computed, ref } from "vue";
import { ElTable } from "element-plus";
import xtTableColumn from "../../../components/xt-table-column/src/main.vue";
import xtButton from "../../../components/xt-button/src/main.vue";
import { formatTimestamp } from "../../../utils/utils";
import Typings from "../../../../typings";

type DataType = Typings.Common.plainObj & {};

// 表格类型
interface Props {
  data: DataType[];
  columns?: Typings.Table.column<DataType>[];
  border?: boolean;
  stripe?: boolean;
  showIndex?: boolean;
  rowKey?: string;
  showSelection?: boolean;
  selectable?: (row: DataType) => boolean;
}

const props = withDefaults(defineProps<Props>(), {
  data: () => [],
  columns: () => [],
  border: true,
  stripe: true,
  showIndex: true,
  rowKey: "id",
  showSelection: false,
});

const emit = defineEmits(["operateClick"]);

// 过滤 column
const convertColumn = computed(() => {
  return props.columns.filter((json) => {
    return !(json.isHide && json.isHide());
  });
});

const instanceRef = ref<InstanceType<typeof ElTable>>();
const getInstance = computed(() => instanceRef.value);
defineExpose({
  instance: getInstance,
});
</script>

<template>
  <el-table
    ref="instanceRef"
    class="xt-table"
    :data="data"
    :border="border"
    :stripe="stripe"
    :row-key="rowKey"
  >
    <slot>
      <xt-table-column
        v-if="showSelection"
        key="selection"
        type="selection"
        width="55"
        :reserve-selection="true"
        :selectable="selectable"
      />

      <xt-table-column
        v-if="showIndex"
        key="index"
        type="index"
        label="序号"
        width="60"
        align="center"
      />

      <xt-table-column
        v-for="{
          prop = '',
          label,
          colType = '',
          format,
          btns,
          renderFn,
          clickFn,
          htmlFn,
          ...col
        } in convertColumn"
        :key="prop"
        :label="label"
        :prop="prop"
        v-bind="col"
      >
        <template #default="scope">
          <!-- 渲染函数 -->
          <template v-if="typeof renderFn === 'function'">
            {{ renderFn(scope) }}
          </template>

          <!-- 时间戳 -->
          <template v-else-if="['time'].includes(colType)">
            {{
              formatTimestamp(scope.row[prop], format || "YYYY-MM-DD HH:mm:ss")
            }}
          </template>

          <!-- 按钮 -->
          <template
            v-else-if="
              ['btn'].includes(colType) && typeof clickFn === 'function'
            "
          >
            <a
              class="btn-column primary"
              href="javascript:;"
              @click="clickFn(scope)"
              >{{ scope.row[prop] }}</a
            >
          </template>

          <!-- html -->
          <template
            v-else-if="
              ['html'].includes(colType) && typeof htmlFn === 'function'
            "
          >
            <span v-html="htmlFn(scope)"></span>
          </template>

          <!-- slot -->
          <template v-else-if="['slot'].includes(colType)">
            <slot :name="prop" v-bind="scope"></slot>
          </template>

          <!-- 操作列 -->
          <template v-else-if="['operate'].includes(colType)">
            <xt-button
              class="operate-column"
              :class="btn.type"
              type="text"
              v-for="btn in btns?.filter((b) => !(b.hideFn && b.hideFn(scope)))"
              :key="btn.name"
              @click="emit('operateClick', btn.handleType, scope)"
            >
              {{ btn.name }}
            </xt-button>
          </template>

          <!-- 其他情况 -->
          <template v-else>
            {{ scope.row[prop] }}
          </template>
        </template>
      </xt-table-column>
    </slot>

    <template #empty>
      <slot name="empty">
        <div class="empty-slot-container">
          <span>暂无数据</span>
        </div>
      </slot>
    </template>
  </el-table>
</template>

<style lang="scss">
@use "../../../scss/xt-table.scss";
</style>
